package org.surelink.radius.middleware.auth;

import org.surelink.radius.cache.ClientCache;
import org.surelink.radius.cache.GroupCache;
import org.surelink.radius.cache.OnlineCache;
import org.surelink.radius.cache.UserCache;
import org.surelink.radius.constant.Constant;
import org.surelink.radius.constant.GroupStatus;
import org.surelink.radius.constant.UserStatus;
import org.surelink.radius.middleware.AuthMiddleware;
import org.surelink.radius.model.Client;
import org.surelink.radius.model.Group;
import org.surelink.radius.model.User;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.tinyradius.packet.AccessRequest;
import org.tinyradius.packet.RadiusPacket;
import org.tinyradius.util.RadiusException;

public class AuthUserMiddleware implements AuthMiddleware
{
    private static final Logger log = Logger.getLogger(AuthUserMiddleware.class);

    @Autowired
    private UserCache userCache;

    @Autowired
    private GroupCache groupCache;

    @Autowired
    private ClientCache clientCache;

    @Autowired
    private OnlineCache onlineCache;

    public RadiusPacket onAuth(User user,AccessRequest request, RadiusPacket response) throws Exception {

        if(log.isInfoEnabled())
            log.info("start AuthUserMiddleware ...");

        if (user == null) {
            response.setPacketType(RadiusPacket.ACCESS_REJECT);
            response.addAttribute("Reply-Message", "用户不存在");
            return response;
        }

        //用户密码校验

        try {
            if (user.getPassword() == null || !request.verifyPassword(user.getPassword())) {
                response.setPacketType(RadiusPacket.ACCESS_REJECT);
                response.addAttribute("Reply-Message", "用户密码错误");
                return response;
            }

        } catch (RadiusException e) {
           throw new Exception(e.getMessage());
        }

        //用户停机判断

        if (UserStatus.Pause.value() == user.getStatus()) {
            response.setPacketType(RadiusPacket.ACCESS_REJECT);
            response.addAttribute("Reply-Message", "用户已经停机");
            return response;
        }

        Group group = groupCache.get(user.getGroupName());
        if(group!=null)
        {
            if (GroupStatus.Pause.value() == group.getStatus()) {
                response.setPacketType(RadiusPacket.ACCESS_REJECT);
                response.addAttribute("Reply-Message", "用户所在组已经停机");
                return response;
            }
        }

        //用户组绑定客户端判断

        String gbClient = groupCache.getGroupMeta(user.getGroupName(), Constant.GROUP_CLIENT.value());

        if(gbClient!=null)
        {
            Client client = clientCache.get(request.getAttributeValue("NAS-IP-Address"));
            if(!client.getAddress().equals(gbClient))
            {
                response.setPacketType(RadiusPacket.ACCESS_REJECT);
                String msg = "用户组绑定客户端不匹配，NAS-IP-Address:%s;UserGroupBind:%s";
                response.addAttribute("Reply-Message",String.format(msg,gbClient,client.getAddress()) );
                return response;
            }
        }

        //并发数限制判断

        String userCnumMeta = userCache.getUserMeta(user.getUserName(), Constant.USER_CONCUR_NUMBER.value());
        String groupCnumMeta = groupCache.getGroupMeta(user.getGroupName(), Constant.GROUP_CONCUR_NUMBER.value());

        int _climit = groupCnumMeta != null ? Integer.valueOf(groupCnumMeta) :0;
        int climit = userCnumMeta != null ? Integer.valueOf(userCnumMeta) : _climit;
        if (climit > 0) {
            int onum = onlineCache.count(user.getUserName());
            if (onum > climit) {
                response.setPacketType(RadiusPacket.ACCESS_REJECT);
                response.addAttribute("Reply-Message", "用户并发达到限制数");
                return response;
            }
        }

        return response;
    }
}


